package com.easylinkin.linkappapi.application.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easylinkin.linkappapi.application.entity.*;
import com.easylinkin.linkappapi.application.mapper.ApplicationMapper;
import com.easylinkin.linkappapi.application.service.ApplicationService;
import com.easylinkin.linkappapi.common.service.CommonAdminService;
import com.easylinkin.linkappapi.deviceunit.entity.DeviceUnit;
import com.easylinkin.linkappapi.security.entity.LinkappPrivilege;
import com.easylinkin.linkappapi.tenant.entity.LinkappTenant;
import com.easylinkin.linkappapi.tenant.mapper.LinkappTenantMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 * 应用管理表 服务实现类
 * </p>
 *
 * @author XuGuoQing
 * @since 2020-05-19
 */
@Service
public class ApplicationServiceImpl extends ServiceImpl<ApplicationMapper, Application> implements ApplicationService {
    @Resource
    private CommonAdminService commonAdminService;

    @Override
    public boolean addApplication(Application application) {
        validParamFormat(application);
        commonAdminService.setCreateAndModifyInfo(application);
        Assert.isTrue(!isApplicationNameExist(application.getName()),"应用名已存在");
        return this.save(application);
    }


    @Override
    public boolean updateApplication(Application application) {
        Assert.notNull(application.getId(), "应用ID不能为空");
        validParamFormat(application);
        Application applicationExist = baseMapper.selectById(application.getId());
        Assert.notNull(applicationExist, "应用不存在");
        boolean isApplicationNameNotRepeat = !isApplicationNameExist(application.getName()) || application.getName().equals(applicationExist.getName());
        Assert.isTrue(isApplicationNameNotRepeat, "应用名称不能重复");
        commonAdminService.setModifyInfo(application);
        return this.updateById(application);
    }

    @Override
    public boolean deleteApplication(List<String> applicationList) {
        Assert.notEmpty(applicationList, "删除应用列表不能为空");
        baseMapper.deleteBatchIds(applicationList);
        return true;
    }

    @Override
    public IPage<Application> getPage(IPage page, Application application) {
        Assert.notNull(page, "分页数据不能为空");
        Assert.notNull(application, "查询对象不能为空");
        return baseMapper.getApplicationByName(page, application.getName());
    }

    @Override
    public List<Application> getApplicationList() {
        QueryWrapper<Application> wrapper = new QueryWrapper<>();
        List<Application>   applicationList  = baseMapper.selectList(wrapper);
        return applicationList;
    }

    @Override
    public Application getApplication(QueryWrapper<Application> wrapper) {
        Application application  = baseMapper.selectOne(wrapper);
        Assert.notNull(application, "应用配置不存在");
        return application;
    }


    /**
     * 校验当前的应用名称是否不存在
     */
    boolean isApplicationNameExist(String applicationName) {
        QueryWrapper<Application> wrapper = new QueryWrapper<>();
        wrapper.eq("name", applicationName);
        List<Application> applicationExist = this.list(wrapper);
        return applicationExist.size() > 0;
    }



    /**
     * 校验参数格式
     */
    private void validParamFormat(Application application) {
        Assert.isTrue(application.getAppKey() != null && application.getAppKey().length() == 32, "AppKey 参数有误,不能空或者超长");
        Assert.isTrue(application.getAppSecret() != null && application.getAppSecret().length() == 64, "AppSecret 参数有误,不能空或者超长");
        Assert.isTrue(application.getDescription() == null||(application.getDescription() != null && application.getDescription().length() <= 200), "参数有误,不能超长");
    }




	@Override
	public List<DeviceUnit> selectDeviceUnitByApplication(String id) {
		return baseMapper.selectDeviceUnitByApplication(id);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void application2DeviceUnits(ApplicationRefDeviceUnitDTO applicationRefDeviceUnitDTO) {
		Application application  = applicationRefDeviceUnitDTO.getApplication();
		application = baseMapper.selectById(application.getId());
		List<DeviceUnit> deviceUnits = applicationRefDeviceUnitDTO.getDeviceUnits();
		List<DeviceUnit> delDeviceUnits = applicationRefDeviceUnitDTO.getDelDeviceUnits();
		baseMapper.deleteApplication2DeviceUnits(application.getId());
		if(deviceUnits!=null && !deviceUnits.isEmpty()) {
			for(DeviceUnit deviceUnit :deviceUnits) {
				ApplicationRefDeviceUnit applicationRefDeviceUnit = new ApplicationRefDeviceUnit();
				applicationRefDeviceUnit.setApplicationId(application.getId());
				applicationRefDeviceUnit.setDeviceUnitId(deviceUnit.getId());
				applicationRefDeviceUnit.setId(UUID.randomUUID().toString().replaceAll("-", ""));
				baseMapper.insertApplication2DeviceUnits(applicationRefDeviceUnit);
			}
		}
		if(application.getAppKey()!=null) {
			List<LinkappTenant> tenants = baseMapper.selectTenantByApplication(application.getAppKey());
			if(tenants!=null && !tenants.isEmpty()) {
				for(LinkappTenant tenant : tenants) {
					if(delDeviceUnits!=null && !delDeviceUnits.isEmpty()) {
						for(DeviceUnit delDeviceUnit :delDeviceUnits) {
							baseMapper.deleteTenant2DeviceUnits(delDeviceUnit.getId(), tenant.getId());
						}
					}
				}
			}
		}
	}

	@Override
	public List<LinkappPrivilege> selectPrivilegeByApplication(String id) {
		return baseMapper.selectPrivilegeByApplication(id);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void application2Privileges(ApplicationRefPrivilegeDTO applicationRefPrivilegeDTO) {
		Application application = applicationRefPrivilegeDTO.getApplication();
		application = baseMapper.selectById(application.getId());
		List<LinkappPrivilege> privileges = applicationRefPrivilegeDTO.getPrivileges();
		List<LinkappPrivilege> delPrivileges = applicationRefPrivilegeDTO.getDelPrivileges();
		baseMapper.deleteApplication2Privileges(application.getId());
		for(LinkappPrivilege privilege :privileges) {
			ApplicationRefPrivilege applicationRefPrivilege = new ApplicationRefPrivilege();
			applicationRefPrivilege.setApplicationId(application.getId());
			applicationRefPrivilege.setPrivilegeId(privilege.getId().toString());
			applicationRefPrivilege.setId(UUID.randomUUID().toString().replaceAll("-", ""));
			baseMapper.insertApplication2Privileges(applicationRefPrivilege);
		}
		if(application.getAppKey()!=null) {
			List<LinkappTenant> tenants = baseMapper.selectTenantByApplication(application.getAppKey());
			if(tenants!=null && !tenants.isEmpty()) {
				for(LinkappTenant tenant : tenants) {
					for(LinkappPrivilege delPrivilege :delPrivileges) {
						baseMapper.deleteTenant2Privileges(delPrivilege.getId().toString(), tenant.getId());
					}

					for(LinkappPrivilege delPrivilege :delPrivileges) {
						baseMapper.deleteRole2Privileges(delPrivilege.getId().toString(), tenant.getId());
					}
				}

			}
		}
	}


	@Autowired
	LinkappTenantMapper linkappTenantMapper ;

	@Override
	public List<Application> selectApplicationByUser(String id) {
		return baseMapper.selectApplicationByUser(id);
	}

	@Override
	public List<LinkappPrivilege> selectApplicationPrivilegeByUser(String id, Integer type) {
		return linkappTenantMapper.selectTenantPrivilegeByUser(id, type);
	}

	@Override
	public List<LinkappPrivilege> selectApplicationPrivilegeCustomByUser(String tenantId ,String id, Integer type) {
		return linkappTenantMapper.selectApplicationPrivilegeCustomByUser(tenantId, id, type);
	}

	@Override
	public List<LinkappPrivilege> selectApplicationPrivilegeMenuByUser(String id) {
		return linkappTenantMapper.selectApplicationPrivilegeMenuByUser(id, 0);
	}


	@Override
	public List<DeviceUnit> selectApplicationDeviceUnitByUser(String id) {
		return linkappTenantMapper.selectTenantDeviceUnitByUser(id);
	}

	@Override
	public List<DeviceUnit> selectApplicationDeviceUnit(String id,String deviceTypeName) {
		return linkappTenantMapper.selectTenantDeviceUnitByUser(id,deviceTypeName);
	}
}
